#Copyright 2009-2010 by Ward, David J ( pymethius@ominian.net )
from twisted.internet.protocol import ServerFactory
from twisted.python.rebuild import Sensitive

import logging
log = logging.getLogger(__name__)
from collections import defaultdict
import weakref
#from functools import partial

from webmud.lib import json
from webmud.lib.wmprotocol import WMProtocol

from ..util.reloadablehandlers import ReloadableHandlers
from auth.responsehandler import ResponseHandler

class WMFactory(Sensitive, ServerFactory):
    protocol = WMProtocol
        
    def __init__(self, realm):
        ReloadableHandlers.reloader(self.__module__)         
        self.realm = realm
        self.defaultUser = realm.getAnonymous
        log.info("Initialized factory")
        
    def buildProtocol(self, addr):
        
        p = self.protocol()
        p.responseHandler = ResponseHandler()
        p.environ = {}
        #Perhaps it is better to have this stuff pushed into the User Object, further separating protocol from user logic
        p.environ["user"] = weakref.proxy(self.defaultUser(addr.port, p))
        p.environ['remote_host'] = addr.host
        p.environ['remote_port'] = addr.port
        p.environ["realm"] = weakref.proxy( self.realm )
        
        p.factory = self
        return p
             
            
    def routeMessage(self, message, environ):
        try:            
            if message.has_key("result"):
                message = json.JSONResponse(**message)
                log.debug("WMFactory.handleCallBack")
                try:
                    environ['protocol'].responseHandler(message, environ)
                except:
                    log.exception("Bad or missing user environmental for callback")
                    try:
                        environ['protocol'].sendError("Missing or bad response id", 500, message.id)
                    except:
                        log.fatal("user.environ.protocol possibly corrupted")
                        environ["protocol"].transport.loseConnection()
                    
                    
            elif message.has_key("method"):
                
                log.debug("WMFactory.handleRequest")
                message = json.JSONRequest(**message)
                try:
                    environ["user"].handleRequest(message, environ)                
                except:
                    log.exception("Bad or missing user request handler")
                    try:
                        environ["protocol"].sendError("Bad or missing request handler", 500, message.id)
                    except:
                        log.fatal("user.environ.protocol possibly corrupted")
                        environ["protocol"].transport.loseConnection()
                
            elif message.has_key("error"):                    
                pass #TODO make a handle error
        except Exception:
            log.exception("WMFactory.defaultProtocolMessage - message %s" % message)                        
        
        
            
        